package com.osce.go_score.service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.csce.domain.entity.go_score.GoScoreExExamMark;
import com.csce.domain.entity.go_score.GoScoreExExamScore;
import com.csce.domain.entity.go_score.GoScoreExam;
import com.csce.domain.entity.go_score.bo.GoScoreExMarkExcelBo;
import com.csce.domain.entity.go_score.bo.GoScoreExMarkScoreExcelBo;
import com.csce.domain.entity.go_score.bo.GoScoreExamDtoIdsBo;
import com.csce.domain.entity.go_score.dto.GoScoreExamDto;
import com.csce.domain.entity.go_score.dto.GoScoreExamPlaceDto;
import com.csce.domain.entity.score.ScoreSheet;
import com.csce.domain.entity.score.ScoreSheetStep;
import com.doudou.core.container.ListUtil;
import com.doudou.core.container.MapUtil;
import com.doudou.core.lang.ObjUtil;
import com.doudou.core.number.DecimalUtil;
import com.doudou.core.date.DateUtil;
import com.osce.common.core.entity.entity.SysUser;
import com.osce.common.utils.SecurityUtils;
import com.osce.go_score.mapper.GoScoreExExamMarkMapper;
import com.osce.go_score.mapper.GoScoreExExamScoreMapper;
import com.osce.interfaces.go_score.IGoScoreExExamMarkService;
import com.osce.interfaces.go_score.IGoScoreExamService;
import com.osce.interfaces.score.IScoreSheetService;
import com.osce.interfaces.system.ISysUserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * 妇产科考试考场学生-分数Service业务层处理
 *
 * @author zzx
 * @since 2024-05-17
 */
@Service
public class GoScoreExExamMarkServiceImpl extends ServiceImpl<GoScoreExExamMarkMapper, GoScoreExExamMark> implements IGoScoreExExamMarkService {

    @Resource private IScoreSheetService scoreSheetService;

    @Resource private GoScoreExExamScoreMapper goScoreExExamScoreMapper;
    @Resource private IGoScoreExamService goScoreExamService;

    @Resource private ISysUserService sysUserService;

    /**
     * 查询妇产科考试考场学生-分数
     *
     * @param goScoreExExamMark 妇产科考试
     * @return 妇产科考试考场学生-分数
     */
    @Override
    @Transactional
    public GoScoreExExamMark selectGoScoreExExamMark(GoScoreExExamMark goScoreExExamMark) {
        goScoreExExamMark.setCreateBy(SecurityUtils.getUserIdStr());
        //查询评分表
        ScoreSheet scoreSheet = scoreSheetService.selectScoreSheetById(goScoreExExamMark.getSheetId());
        //查询学员成绩是否存在
        GoScoreExExamMark selectMark = baseMapper.selectGoScoreExExamMark(goScoreExExamMark);
        List<GoScoreExExamScore> goScoreExExamScores;
        if (ObjUtil.isEmpty(selectMark)){//不存在，去创建
            selectMark = goScoreExExamMark.copy();
            insertGoScoreExExamMark(selectMark.createScores(scoreSheet.getSteps()));
            goScoreExExamScores = selectMark.getGoScoreExExamScores();
        }else {
            goScoreExExamScores = goScoreExExamScoreMapper.selectGoScoreExExamScoreListByMarkId(selectMark.getId());
        }
        Map<Long, BigDecimal> scoreMap = goScoreExExamScores.stream().collect(Collectors.toMap(GoScoreExExamScore::getStepId, GoScoreExExamScore::getScore));
        //整合成绩
        for (ScoreSheetStep step : scoreSheet.getSteps()) {
            step.setMark(scoreMap.get(step.getId()));
        }
        selectMark.setScoreSheet(scoreSheet);
        return selectMark;
    }

    /**
     * 查询妇产科考试考场学生-分数列表
     *
     * @param goScoreExExamMark 妇产科考试考场学生-分数
     * @return 妇产科考试考场学生-分数
     */
    @Override
    public List<GoScoreExExamMark> selectGoScoreExExamMarkList(GoScoreExExamMark goScoreExExamMark) {
        return baseMapper.selectGoScoreExExamMarkList(goScoreExExamMark);
    }

    /**
     * 新增妇产科考试考场学生-分数
     *
     * @param goScoreExExamMark 妇产科考试考场学生-分数
     * @return 结果
     */
    @Override
    @Transactional
    public int insertGoScoreExExamMark(GoScoreExExamMark goScoreExExamMark) {
        int i = baseMapper.insertGoScoreExExamMark(goScoreExExamMark);
        //添加步骤得分
        goScoreExExamScoreMapper.batchInsertGoScoreExExamScore(goScoreExExamMark.getId(),goScoreExExamMark.getGoScoreExExamScores());
        return i;
    }

    /**
     * 修改妇产科考试考场学生-分数
     *
     * @param goScoreExExamMark 妇产科考试考场学生-分数
     * @return 结果
     */
    @Override
    @Transactional
    public GoScoreExExamMark updateGoScoreExExamMark(GoScoreExExamMark goScoreExExamMark) {
        goScoreExExamMark.setCreateBy(SecurityUtils.getUserIdStr());
        goScoreExExamMark.setCreateTime(DateUtil.date());
        goScoreExExamMark.createScores();
        goScoreExExamMark.setScore(ListUtil.sumDecimalByKey(goScoreExExamMark.getGoScoreExExamScores(),"score"));//总分
        goScoreExExamScoreMapper.deleteGoScoreExExamScoreByMarkId(goScoreExExamMark.getId());
        int i = baseMapper.updateGoScoreExExamMark(goScoreExExamMark);
        goScoreExExamScoreMapper.batchInsertGoScoreExExamScore(goScoreExExamMark.getId(),goScoreExExamMark.getGoScoreExExamScores());
        if (i > 0){
            return goScoreExExamMark;
        }
        return null;
    }

    /**
     * 批量删除妇产科考试考场学生-分数
     *
     * @param examIds 需要删除的妇产科考试考场学生-分数主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteGoScoreExExamMarkByExamIds(Long[] examIds) {
        goScoreExExamScoreMapper.deleteGoScoreExExamScoreByExamIds(examIds);
        int i = baseMapper.deleteGoScoreExExamMarkByExamIds(examIds);
        return i;
    }

    /**
     * 删除妇产科考试考场学生-分数信息
     *
     * @param examId 妇产科考试考场学生-分数主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteGoScoreExExamMarkByExamId(Long examId) {
        goScoreExExamScoreMapper.deleteGoScoreExExamScoreByExamIds(examId);
        int i = baseMapper.deleteGoScoreExExamMarkByExamId(examId);
        return i;
    }

    /**
     * 导出妇产科考试考场学生-分数列表
     */
    @Override
    public List<GoScoreExMarkScoreExcelBo> exportGoScoreExExamMarkList(GoScoreExExamMark goScoreExExamMark){
        List<GoScoreExMarkScoreExcelBo> goScoreExMarkScoreExcelBos = ListUtil.linkedList();
        Map<Long,GoScoreExMarkScoreExcelBo> goScoreExMarkScoreExcelBoMap = MapUtil.hashMap();
        //查询考试
        GoScoreExam goScoreExam = goScoreExamService.selectGoScoreExamById(goScoreExExamMark.getExamId());
        Date examDate = goScoreExam.getDate();//日期
        GoScoreExamDto goScoreExamDto = goScoreExam.convertGoScoreExamDto();//转成dto，获取到学生和教师的id，一次性全部查询出来
        GoScoreExamDtoIdsBo allIds = goScoreExamDto.getAllIds();
        Set<Long> sheetList = allIds.getSheetList();
        Map<Long, String> sheetMap = scoreSheetService.selectScoreSheetListByIds(sheetList).stream().collect(Collectors.toMap(ScoreSheet::getId, ScoreSheet::getName));
        List<SysUser> sysUsers = sysUserService.selectUserListByIds(allIds.getUserList());
        Map<Long, SysUser> userMap = sysUsers.stream().collect(Collectors.toMap(SysUser::getUserId,o->o));

        List<GoScoreExamPlaceDto> goScoreExamPlaceList = goScoreExamDto.getGoScoreExamPlaceList();//场地列表
        List<GoScoreExMarkExcelBo> studentDataList = ListUtil.linkedList();
        for (int i = 0; i < goScoreExamPlaceList.size(); i++) {//遍历场地
            GoScoreExamPlaceDto goScoreExamPlace = goScoreExamPlaceList.get(i);
            List<Long> userIdList = goScoreExamPlace.getStudentIdList();//当前考站的学员
            List<Long> teacherIds = goScoreExamPlace.getTeacherIds();//当前考站的考官
            List<Long> sheetIds = goScoreExamPlace.getSheetIds();//当前考站的评分表

            for (Long userId : userIdList) {//遍历学员
                GoScoreExMarkScoreExcelBo goScoreExMarkScoreExcelBo = goScoreExMarkScoreExcelBoMap.getOrDefault(userId, new GoScoreExMarkScoreExcelBo());
                for (Long sheetId : sheetIds) {//遍历评分表
                    String sheetName = sheetMap.get(sheetId);
                    for (Long teacherId : teacherIds) {//遍历教师
                        SysUser teacher = userMap.get(teacherId);
                        GoScoreExExamMark build = GoScoreExExamMark.builder().examId(goScoreExam.getId()).examPlaceId(goScoreExamPlace.getId()).examStudentId(userId).sheetId(sheetId).build();
                        build.setCreateBy(teacherId+"");
                        List<GoScoreExExamMark> goScoreExExamMarks = baseMapper.selectGoScoreExExamMarkList(build);
                        GoScoreExMarkExcelBo goScoreExMarkExcelBo = new GoScoreExMarkExcelBo();
                        goScoreExMarkExcelBo.setExaminer(teacher.getNickName());
                        if (ListUtil.isNotEmpty(goScoreExExamMarks)){
                            GoScoreExExamMark mark = ListUtil.getFirst(goScoreExExamMarks);
                            goScoreExMarkExcelBo.setScore(mark.getScore());
                        }else {
                            goScoreExMarkExcelBo.setScore(DecimalUtil.newZero());
                        }
                        goScoreExMarkScoreExcelBo.addSheets(sheetName,goScoreExMarkExcelBo);
                    }
                }
                goScoreExMarkScoreExcelBoMap.put(userId,goScoreExMarkScoreExcelBo);
            }
        }

        AtomicInteger index = new AtomicInteger(1);
        goScoreExMarkScoreExcelBoMap.forEach((userId,bo)->{
            SysUser sysUser = userMap.get(userId);
            bo.setIndex(index.get());
            bo.setDate(DateUtil.formatDate(examDate));
            bo.setUsername(sysUser.getNickName());
            bo.setUsercode(sysUser.getUserName());
            bo.setUserremark(sysUser.getRemark());
            goScoreExMarkScoreExcelBos.add(bo);
            index.addAndGet(1);
        });
//        FileUtil.writeString(JSONUtil.toJsonPrettyStr(goScoreExMarkScoreExcelBos),new File("D:\\work_resource\\jiayi\\code\\osce-new\\osce-new-master\\sql\\doudou.json"), Charset.defaultCharset());



        //导出excel
//        JSONObject dataObj = JSONUtil.parseObj(goScoreExMarkScoreExcelBo);
//        JxlsExcel.exportExcel("go_exam_score_template.xlsx",outputStream,dataObj);
        return goScoreExMarkScoreExcelBos;
    }
}









